#ifndef TESTFUNCTIONS_H
#define TESTFUNCTIONS_H

#include <gtest/gtest.h>

#include "../../QueryDataManipulation/src/QueryDataManipulation.hpp"

template<typename Data, typename DataIterator> void testWhereFunction(const std::vector<Data>& data, QDM::QueryDataManipulation<DataIterator>& query, WhereFunction isRequered)
{
	const std::vector<DataIterator>& filtredElements = query.from(data.cbegin(), data.size()).where(isRequered).result();

	std::vector<DataIterator> trueFiltredElements;

	for (size_t i = 0; i < data.size(); i++)
	{
		DataIterator item = data.begin() + i;

		if (isRequered(item))
		{
			trueFiltredElements.push_back(item);
		}
	}

	ASSERT_TRUE(trueFiltredElements.size() == filtredElements.size());

	for (size_t i = 0; i < filtredElements.size(); i++)
	{
		EXPECT_TRUE(trueFiltredElements[i] == filtredElements[i]);
	}
}

template<typename Data, typename DataIterator> void testOrderByFunction(const std::vector<Data>& data, QDM::QueryDataManipulation<DataIterator>& query, OrderByFunction isNeedChanged)
{
	const std::vector<DataIterator>& sortedElements = query.from(data.begin(), data.size()).orderBy(isNeedChanged).result();

	for (size_t i = 0; i < data.size() - 1; i++)
	{
		ASSERT_TRUE(!isNeedChanged(sortedElements[i], sortedElements[i + 1])) << "I - " << i << " : " << *sortedElements[i] << " " << *sortedElements[i + 1];
	}
}

template<typename Data, typename DataIterator, typename SelectType, typename SelecTypetIterator> void testSelectAndExecuteFunctions(const std::vector<Data>& data, const QDM::IKernel<DataIterator, SelectType>& kernel, const QDM::IKernel<SelecTypetIterator>& executeKernel)
{
	QDM::QueryDataManipulation<DataIterator, SelectType> query(&kernel);

	std::vector<SelectType>& selectedElements = query.from(data.begin(), data.size())
													.select([](const DataIterator& item){return (float)(*item);});

	QDM::QueryDataManipulation<SelecTypetIterator> executeQuery(&executeKernel);

	executeQuery.from(selectedElements.begin(), selectedElements.size())
				.execute([](std::vector<SelecTypetIterator>& data, int i){printf("\nThread - %i;\n", i);});

	EXPECT_TRUE(selectedElements.size() == data.size());
}


#endif